package com.zhangdy.agent.service.impl;

import com.zhangdy.agent.common.dto.LoadClass;
import com.zhangdy.agent.common.dto.ReturnT;
import com.zhangdy.agent.common.utils.AgentRemotingUtil;
import com.zhangdy.agent.entity.MethodPoint;
import com.zhangdy.agent.entity.MethodPointRule;
import com.zhangdy.agent.enums.RuleEnum;
import com.zhangdy.agent.enums.RuleTypeEnum;
import com.zhangdy.agent.exception.AgentException;
import com.zhangdy.agent.mapper.MethodPointRuleMapper;
import com.zhangdy.agent.service.MethodPointRuleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhangdy.agent.service.MethodPointService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zhangdy
 * @since 2022-01-06
 */
@Service
public class MethodPointRuleServiceImpl extends ServiceImpl<MethodPointRuleMapper, MethodPointRule>
        implements MethodPointRuleService {
    private static Logger logger = LoggerFactory.getLogger(MethodPointRuleServiceImpl.class);


    @Autowired
    MethodPointService methodPointService;

    @Override
    public void syncRule(Long id) {
        MethodPointRule serverMethodRule = this.getById(id);
        MethodPoint remoteMethodPoint = methodPointService.getById(serverMethodRule.getRemoteServerId());
        String serverPath = remoteMethodPoint.getServerPath();
        if (serverPath == null || serverPath.trim().length() == 0) {
            serverPath = "";
        }
        String redefineClassUrl  = "http://" + remoteMethodPoint.getServerIp() + ":" + remoteMethodPoint.getServerPort() + "/" + serverPath + "/redefineClass";
        String sourceCode = serverMethodRule.getSourceCode();
        if (serverMethodRule.getRuleType() == RuleTypeEnum.JAVA_CLASS.getType()) {
            String loadClassUrl  = "http://" + remoteMethodPoint.getServerIp() + ":" + remoteMethodPoint.getServerPort() +"/"  + serverPath + "/loadClass";

            LoadClass loadClass = new LoadClass();
            loadClass.setSourceCode(serverMethodRule.getSourceCode());
            loadClass.setClassName(serverMethodRule.getClassReference());
            ReturnT<String> returnT = AgentRemotingUtil.postBody(loadClassUrl,    loadClass,  String.class);
            if (returnT.getCode() == ReturnT.SUCCESS_CODE) {
                sourceCode = returnT.getContent().toString();
            } else {
                logger.error("{}", returnT);
                throw new AgentException("source code compile exception ");
            }
        }

        logger.info("sourceCode：{}", sourceCode);

        com.zhangdy.agent.common.dto.MethodPoint methodPoint = new com.zhangdy.agent.common.dto.MethodPoint();
        methodPoint.setPackageName(remoteMethodPoint.getPackageName());
        methodPoint.setClassName(remoteMethodPoint.getClassName());
        methodPoint.setMethodName(remoteMethodPoint.getMethodName());

        String methodArgsType = remoteMethodPoint.getMethodArgsType();

        if (methodArgsType != null && methodArgsType.trim().length() > 0) {
            String[] array = methodArgsType.split(",");
            List<String> argsTypeList = new ArrayList<>(Arrays.asList(array));

            methodPoint.setArgsTypeList(argsTypeList);
        }
        Integer rule = serverMethodRule.getRule();

        if (RuleEnum.BEFORE.getRule() == rule) {
            methodPoint.setBeforeCode(sourceCode);
        } else if (RuleEnum.AFTER.getRule() == rule) {
            methodPoint.setAfterCode(sourceCode);
        } else if (RuleEnum.REPLACE.getRule() == rule) {
            methodPoint.setReplaceCode(sourceCode);
        }
        ReturnT returnT = AgentRemotingUtil.postBody(redefineClassUrl,  methodPoint, String.class);
        logger.info("{}", returnT);
        if (returnT.getCode() != ReturnT.SUCCESS_CODE) {
            throw new AgentException(" redefine exception ");

        }

    }
}
